package com.zhengbo.flink.demo.base.codis.impl;

import com.zhengbo.flink.demo.base.codis.CodisClient;
import com.zhengbo.flink.demo.base.codis.CodisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.util.Pool;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * @author geely
 */
@Component(value = "codisService")
public class CodisServiceImpl implements CodisService {

    private static Logger logger = LoggerFactory.getLogger(CodisServiceImpl.class);

    @Autowired
    private CodisClient codisClient;

    @Override
    public String set(String key, String value) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.set(key, value);
                } else {
                    logger.error(String.format("set key-> %s,value ->%s jedis is null !", key, value));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("set key-> %s,value ->%s error!", key, value), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("set key-> %s,value ->%s  jedisPool is null !", key, value));
        }
        return null;
    }

    @Override
    public String setex(String key, int seconds, String value) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.setex(key, seconds, value);
                } else {
                    logger.error(String.format("setex key-> %s,value ->%s ,seconds->%s jedis is null !", key, value, seconds));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("setex key-> %s,value ->%s  ,seconds->%s  error!", key, value, seconds), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("setex key-> %s,value ->%s ,seconds->%s jedisPool is null !", key, value, seconds));
        }
        return null;
    }

    @Override
    public String get(String key) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.get(key);
                } else {
                    logger.error(String.format("get key-> %s,value ->%s ,seconds->%s jedis is null !", key));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("get key-> %s,value ->%s  ,seconds->%s  error!", key), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }
        } else {
            logger.error(String.format("get key-> %s jedisPool is null !", key));
        }
        return null;
    }

    @Override
    public Long decr(String key) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.decr(key);
                } else {
                    logger.error(String.format("decr key-> %s,value ->%s ,seconds->%s jedis is null !", key));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("decr key-> %s,value ->%s  ,seconds->%s  error!", key), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("decr key-> %s jedisPool is null !", key));
        }
        return null;
    }

    @Override
    public Long decrBy(String key, long step) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.decrBy(key, step);
                } else {
                    logger.error(String.format("decrBy key-> %s,step ->%s jedis is null !", key, step));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("decrBy key-> %s,step ->%s error!", key, step), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("decrBy key-> %s,step ->%s  jedisPool is null !", key, step));
        }
        return null;
    }

    @Override
    public Long incrBy(String key, long step) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.incrBy(key, step);
                } else {
                    logger.error(String.format("incrBy key-> %s,step ->%s jedis is null !", key, step));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("incrBy key-> %s,step ->%s error!", key, step), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("incrBy key-> %s,step ->%s  jedisPool is null !", key, step));
        }
        return null;
    }

    @Override
    public Long incr(String key) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.incr(key);
                } else {
                    logger.error(String.format("incr key-> %s jedis is null !", key));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("incr key-> %s error!", key), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("incrBy key-> %s  jedisPool is null !", key));
        }
        return null;
    }

    @Override
    public Long del(String key) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.del(key);
                } else {
                    logger.error(String.format("del key-> %s jedis is null !", key));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("del key-> %s,step error!", key), e);
            } finally {
                if (jedisPool != null && jedis != null) {

                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("del key-> %s jedisPool is null !", key));
        }
        return null;
    }
    @Override
    public Long dels(String ... keys) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.del(keys);
                } else {
                    logger.error(String.format("del key-> %s jedis is null !", keys));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("del key-> %s,step error!", keys), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("del key-> %s jedisPool is null !", keys));
        }
        return null;

    }
    @Override
    public Long delPipeline(String ... keys) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        Pipeline pipe =null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    pipe=jedis.pipelined();// 先创建一个pipeline的链接对象
                    for (String key:keys){
                        pipe.del(key);
                    }
                    Long resultAll=0l;
                    List<Object> resultList= pipe.syncAndReturnAll();
                    if(resultList!=null && resultList.size()>0){
                        try{
                            for(int n=0;n<resultList.size();n++){
                                resultAll=Long.parseLong(resultList.get(n).toString());
                            }
                        }catch(Exception e){
                          logger.error("delPipeline:{}",e);
                        }

                    }
                    return resultAll;
                } else {
                    logger.error(String.format("del key-> %s jedis is null !", keys));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("del key-> %s,step error!", keys), e);
            } finally {
                if(pipe!=null){
                    try {
                        pipe.close();
                    }catch (Exception e){
                        logger.error(String.format("pipe close error ,step error!"), e);
                    }

                }
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("del key-> %s jedisPool is null !", keys));
        }
        return null;
    }

    @Override
    public Long expire(String key, int seconds) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.expire(key, seconds);
                } else {
                    logger.error(String.format("expire key-> %s ,seconds->%s jedis is null !", key, seconds));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("expire key-> %s,seconds->%s error!", key, seconds), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("del key-> %s,seconds ->%s  jedisPool is null !", key, seconds));
        }
        return null;
    }

    @Override
    public Long ttl(String key) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.ttl(key);
                } else {
                    logger.error(String.format("ttl key-> %s  jedis is null !", key));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("ttl key-> %s error!", key), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("ttl key-> %s jedisPool is null !", key));
        }
        return null;
    }


    @Override
    public Long setnx(String key, String value) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.setnx(key, value);
                } else {
                    logger.error(String.format("setnx key-> %s ,value->%s jedis is null !", key, value));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("setnx key-> %s,value->%s error!", key, value), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("setnx key-> %s,value ->%s  jedisPool is null !", key, value));
        }
        return null;
    }

    @Override
    public String hget(String key, String field) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.hget(key, field);
                } else {
                    logger.error(String.format("hget key-> %s ,field->%s jedis is null !", key, field));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("hget key-> %s,field->%s error!", key, field), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("hget key-> %s,field ->%s  jedisPool is null !", key, field));
        }
        return null;
    }

	@Override
	public Map<String, String> hgetAll(String hkey) {
		if(StringUtils.isEmpty(hkey)){
			throw new IllegalArgumentException("hgetAll 参数为空！");
		}
		//get value
		Map<String, String> valueMap =new HashMap<>();
		Pool<Jedis> jedisPool = null;
		Jedis jedis =null;
		try {
			if(null ==(jedisPool =codisClient.getJedisPool()) || null ==(jedis =jedisPool.getResource())){
				logger.error("jedis or pipeline 为空！");
				return valueMap;
			}
			valueMap = jedis.hgetAll(hkey);
		} catch (Exception e) {
			logger.error("jedis hgetAll err，hkey:{}", hkey, e);
		} finally {
			codisClient.returnResource(jedisPool, jedis);
		}
		return valueMap;
	}

	@Override
	public Long hset(String hkey, String field, String value) {
		if(StringUtils.isEmpty(hkey) || StringUtils.isEmpty(field)){
			throw new IllegalArgumentException("hset 参数为空！");
		}
		//get value
		Long hsetResult =0L;
		Pool<Jedis> jedisPool = null;
		Jedis jedis =null;
		try {
			if(null ==(jedisPool =codisClient.getJedisPool()) || null ==(jedis =jedisPool.getResource())){
				logger.error("jedis or pipeline 为空！");
				return hsetResult;
			}
			hsetResult = jedis.hset(hkey, field, value);
		} catch (Exception e) {
			logger.error("jedis hgetAll err，hkey:{}", hkey, e);
		} finally {
			codisClient.returnResource(jedisPool, jedis);
		}
		return hsetResult;
	}

	@Override
	public Boolean exists(String key) {
		if(StringUtils.isEmpty(key)){
			throw new IllegalArgumentException("hgetAll 参数为空！");
		}
		//get value
		Pool<Jedis> jedisPool = null;
		Jedis jedis =null;
		try {
			if(null ==(jedisPool =codisClient.getJedisPool()) || null ==(jedis =jedisPool.getResource())){
				logger.error("jedis or pipeline 为空！");
				return null;
			}
			return jedis.exists(key);
		} catch (Exception e) {
			logger.error("jedis exists err，key:{}", key, e);
		} finally {
			codisClient.returnResource(jedisPool, jedis);
		}
		return false;
	}

	@Override
    public Set<String> smembers(String key) {
        Pool<Jedis> jedisPool = codisClient.getJedisPool();
        Jedis jedis = null;
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                if (jedis != null) {
                    return jedis.smembers(key);
                } else {
                    logger.error(String.format("smembers key-> %s jedis is null !", key));
                    return null;
                }
            } catch (Exception e) {
                logger.error(String.format("smembers key-> %s error!", key), e);
            } finally {
                if (jedisPool != null && jedis != null) {
                    codisClient.returnResource(jedisPool, jedis);
                }
            }

        } else {
            logger.error(String.format("smembers key-> %s jedisPool is null !", key));
        }
        return null;
    }
}
